package com.xiaohh.user.exceptions.advices;

import com.xiaohh.user.constants.BizCodeEnum;
import com.xiaohh.user.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 前端统一的异常处理类
 * </p>
 *
 * @author XiaoHH
 * @version 1.0
 * @date 2021-03-04 星期四 20:17:18
 * @file HandleControllerAdvice.java
 */
@Slf4j // 导入日志
@RestControllerAdvice(basePackages = {"com.xiaohh.user.controllers"})  // 标注这是一个统一的异常处理类
public class HandleControllerAdvice {

    /**
     * 数据校验错误异常
     *
     * @param e 异常对象
     * @return 异常信息
     */
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    public R handleValidateException(MethodArgumentNotValidException e) {
        // 打印日志
        log.error("数据校验出现问题", e);

        // 获取校验错误结果对象
        BindingResult result = e.getBindingResult();

        Map<String, String> validate = new HashMap<String, String>();
        // 获取错误的校验错误信息
        result.getFieldErrors().forEach(item -> {
            // 是哪个属性不合法
            String field = item.getField();
            // 不合法的默认消息
            String message = item.getDefaultMessage();
            // 封装错误信息
            validate.put(field, message);
        });
        return R.error(BizCodeEnum.VALIDATE_EXCEPTION.getCode(), BizCodeEnum.VALIDATE_EXCEPTION.getMessage()).put("data", validate);
    }

    /**
     * 处理数据完整性异常
     *
     * @param e 异常对象
     * @return 返回结果
     */
    @ExceptionHandler(value = DataIntegrityViolationException.class)
    public R handleDataIntegrityViolationException(DataIntegrityViolationException e) {
        log.error(BizCodeEnum.DATA_INTEGRITY_VIOLATION_EXCEPTION.getMessage(), e);
        return R.error(BizCodeEnum.DATA_INTEGRITY_VIOLATION_EXCEPTION);
    }

    /**
     * 处理所有异常的异常处理类
     *
     * @param t 异常对象
     * @return 返回处理结果
     */
    @ExceptionHandler(value = Throwable.class)
    public R handleThrowable(Throwable t) {
        // 记录一下日志
        log.error(BizCodeEnum.UNKNOWN_EXCEPTION.getMessage(), t);
        return R.error(BizCodeEnum.UNKNOWN_EXCEPTION);
    }
}
